package cc.fs.kotlin.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * 获取图片(相册or拍照)
 * <code>
 * 调用方式：
 * helper = new SelectPhotoHelper(helper, listener).show();
 * 回调处理：
 * helper.onActivityResult(requestCode, resultCode, data);
 * </code>
 */
public class SelectPhotoHelper {

    private final String TAG = "-SelectPhotoHelper-";

    /**
     * 使用照相机拍照获取图片
     */
    public static final int SELECT_PIC_BY_TACK_PHOTO = 1;
    /**
     * 使用相册中的图片
     */
    public static final int SELECT_PIC_BY_PICK_PHOTO = 2;

    public static enum Status {
        /** 取消 */
        CANCEL,
        /** 找不到图片文件 */
        NOTFOND,
        /** 没有SDCard */
        NOSDCARD,
        /** 获取不到系统数据 */
        NODATA
    }
    public static enum Source {
        /** 相册 */
        PhotoGallery("相册"),
        /** 拍照 */
        Camera("拍照");

        private String name;
        Source(String name){
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
    }

    public static interface OnGetPhotoListener {
        public void onSuccess(String path);
        public void onFail(Status status);
    }

    private String mTitle = "选取图片";
    private List<Source> mSources = null;

    /**
     * 获取到的图片路径
     */
    private String picPath;
    private Activity mContext;
    private OnGetPhotoListener mListener;

    private Uri takeUri;

    public SelectPhotoHelper(Activity context, OnGetPhotoListener listener) {
        mContext = context;
        mListener = listener;

        if (context == null) {
            throw  new IllegalArgumentException("context不能为空");
        }
        if (listener == null) {
            throw  new IllegalArgumentException("listener不能为空");
        }
    }

    /**
     * 设置标题（图片来源多项时提示）
     * @param title
     * @return
     */
    public SelectPhotoHelper setTitle(String title) {
        if (!TextUtils.isEmpty(title)) {
            this.mTitle = title;
        }
        return this;
    }
    /**
     * 设置标题（图片来源多项时提示）
     * @param titleRes
     * @return
     */
    public SelectPhotoHelper setTitle(int titleRes) {
        return setTitle(mContext.getString(titleRes));
    }

    /**
     * 使用图片来源
     * @param source 相册or拍照
     * @return
     */
    public SelectPhotoHelper useSource(Source source) {
        if (source == null) {
            return this;
        }

        if (mSources == null) {
            mSources = new ArrayList<Source>();
        }
        mSources.add(source);
        return this;
    }

    /**
     * 开始获取照片
     */
    public void show() {
        final Source[] sources;
        if (mSources == null || mSources.isEmpty()) {
            sources = Source.values();
        } else {
            sources = new Source[mSources.size()];
            mSources.toArray(sources);
        }

        if (sources.length == 1) {
            startGetPhoto(sources[0]);
            return;
        }

        List<String> selects = new ArrayList<String>();
        for (int i=0; i<sources.length; i++) {
            selects.add(sources[i].getName());
        }

        String[] array = new String[selects.size()];
        array = selects.toArray(array);
       new AlertDialog.Builder(mContext).setTitle(mTitle).setItems(array, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int position) {
                Source source = sources[position];
                startGetPhoto(source);
                dialog.dismiss();
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mListener.onFail(Status.CANCEL);
            }
        }).show();
    }

    private void startGetPhoto(Source source) {
        switch (source) {
            case PhotoGallery:
                pickPhoto();
                break;
            case Camera:
                takePhoto();
                break;
        }
    }


    /**
     * 拍照获取图片
     */
    private void takePhoto() {
        //执行拍照前，应该先判断SD卡是否存在
        String SDState = Environment.getExternalStorageState();
        if (SDState.equals(Environment.MEDIA_MOUNTED)) {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//"android.media.action.IMAGE_CAPTURE"
            /***
             * 需要说明一下，以下操作使用照相机拍照，拍照后的图片会存放在相册中的
             * 这里使用的这种方式有一个好处就是获取的图片是拍照后的原图
             * 如果不实用ContentValues存放照片路径的话，拍照后获取的图片为缩略图不清晰
             */
            ContentValues values = new ContentValues();
            takeUri = mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, takeUri);
            /**-----------------*/
            mContext.startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);
        } else {
            mListener.onFail(Status.NOSDCARD);
        }
    }

    /**
     * 从相册中取图片
     */
    private void pickPhoto() {
        Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/jpeg");
        mContext.startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            doPhoto(requestCode, data);
        } else {
            mListener.onFail(Status.CANCEL);
        }
    }



    @TargetApi(Build.VERSION_CODES.KITKAT)
    private String getPath(final Uri uri) {
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(mContext, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] {
                        split[1]
                };

                return getDataColumn(contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param uri The Uri to query.
     * @param selection (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    private String getDataColumn(Uri uri, String selection,
                                 String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = mContext.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } catch (Exception e) {
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    private boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
    private String selectImage(Intent data){
        if (data == null) {
            return null;
        }

        Uri selectedImage = data.getData();
        if (selectedImage == null) {
            return null;
        }

        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        try {
            Cursor cursor = mContext.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            if (cursor == null) {
                return null;
            }
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                try {
                    cursor.close();
                } catch (Exception e) {
                    Log.e(TAG,e.toString());
                }
            }
            return picturePath;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 选择图片后，获取图片的路径
     *
     * @param requestCode
     * @param data
     */
    private void doPhoto(int requestCode, Intent data) {
        // 从相册取图片
        if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {
            if (data == null) {
                mListener.onFail(Status.NODATA);
                return;
            }

            takeUri = data.getData();
            if (takeUri == null) {
                mListener.onFail(Status.NODATA);
                return;
            }
        }

        if (takeUri != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                picPath = getPath(takeUri);
            }
        }
        if (TextUtils.isEmpty(picPath)) {
            picPath = selectImage(data);
        }

        if (picPath != null && (picPath.toUpperCase().endsWith(".PNG") || picPath.toUpperCase().endsWith(".JPG"))) {
            mListener.onSuccess(picPath);
        } else {
            mListener.onFail(Status.NOTFOND);
        }
    }

}
